package com.cookor.poi.modules.phy.service;

import com.cookor.poi.common.persistence.DataEntity;
import com.cookor.poi.common.persistence.Page;
import com.cookor.poi.common.service.CrudService;
import com.cookor.poi.common.utils.DateUtils;
import com.cookor.poi.common.utils.IdGen;
import com.cookor.poi.common.utils.StringUtils;
import com.cookor.poi.modules.phy.dao.FSchedueDao;
import com.cookor.poi.modules.phy.dao.TOrderDao;
import com.cookor.poi.modules.phy.dto.StockDto;
import com.cookor.poi.modules.phy.entity.FSchedue;
import com.cookor.poi.modules.phy.entity.TAction;
import com.cookor.poi.modules.phy.entity.TBookNo;
import com.cookor.poi.modules.phy.entity.TDoctor;
import com.cookor.poi.modules.phy.entity.TOrder;
import com.cookor.poi.modules.phy.entity.TPatient;
import com.cookor.poi.modules.phy.entity.TSchedue;
import com.cookor.poi.modules.phy.entity.TStock;
import com.cookor.poi.modules.phy.entity.TTempNotice;
import com.cookor.poi.modules.phy.schedule.AppointSchedule;
import com.cookor.poi.modules.tenant.entity.TTenant;
import com.cookor.poi.modules.tenant.service.TTenantService;
import com.cookor.poi.modules.weixin.account.PlatformAccount;
import com.cookor.poi.modules.weixin.entity.TWeixinConfig;
import com.cookor.poi.modules.weixin.open.WxOpenUtil;
import com.cookor.poi.modules.weixin.service.TWeixinConfigService;
import com.cookor.poi.modules.weixin.utils.TempNoticeUtil;
import com.xiaoleilu.hutool.json.JSONObject;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TOrderService extends CrudService<TOrderDao, TOrder> {
    @Autowired
    private TBookNoService tBookNoService;

    @Autowired
    private TPatientService tPatientService;

    @Autowired
    private TDoctorService tDoctorService;

    @Autowired
    private TTenantService tTenantService;

    @Autowired
    private TStockService tStockService;

    @Autowired
    private TSchedueService tSchedueService;

    @Autowired
    private TActionService tActionService;

    @Autowired
    private TTempNoticeService tTempNoticeService;

    @Autowired
    private TWeixinConfigService tWeixinConfigService;

    @Autowired
    private FSchedueService fSchedueService;

    @Autowired
    private FSchedueDao fSchedueDao;

    @Autowired
    private FSchedueTemplateService fSchedueTemplateService;

    public TOrder get(String id) {
        return (TOrder) super.get(id);
    }

    public TOrder getByOrderNo(String orderNo) {
        return ((TOrderDao) this.dao).getByOrderNo(orderNo);
    }

    public List<TOrder> findList(TOrder tOrder) {
        return super.findList(tOrder);
    }

    public Page<TOrder> findPage(Page<TOrder> page, TOrder tOrder) {
        return super.findPage(page, tOrder);
    }

    @Transactional(readOnly = false)
    public void save(TOrder tOrder) {
        super.save(tOrder);
    }

    @Transactional(readOnly = false)
    public void delete(TOrder tOrder) {
        super.delete(tOrder);
    }

    @Transactional(readOnly = false, rollbackFor = {Exception.class})
    public void createOrderV2(Integer year, String date, Integer index, String title, String beginDate, String endDate, Integer patientId, String openId, Integer tenantId) throws Exception {
        if (tenantId == null || patientId == null || year == null || index == null ||
                StringUtils.isBlank(openId) || StringUtils.isBlank(date) || StringUtils.isBlank(title) ||
                StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate))
            throw new Exception("参数错误");
        TPatient tPatient = this.tPatientService.get(patientId.toString());
        TOrder orderQuery = new TOrder();
        orderQuery.setTenantId(tenantId);
        orderQuery.setStatus(Integer.valueOf(11));
        orderQuery.setPatientCard(tPatient.getCard());
        orderQuery.setQueryOrderNo(String.valueOf(year).substring(2) + date.split("-")[0]);
        List<TOrder> oldOrders = findList(orderQuery);
        if (oldOrders.size() >= 3)
            throw new Exception("该身份证号本月已取消超过三次，不能再预约了！");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date bookDate = sdf.parse(year.toString() + "-" + date);
        orderQuery = new TOrder();
        orderQuery.setBookDate(bookDate);
        orderQuery.setBookDateType(index);
        orderQuery.setTenantId(tenantId);
        oldOrders = findList(orderQuery);
        for (TOrder order : oldOrders) {
            if (order.getPatientId() == patientId && order.getStatus().intValue() != 11)
                throw new Exception("已预约过该时间段！");
        }
        sdf = new SimpleDateFormat("MM-dd");
        Date parse = sdf.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(parse);
        Integer month = Integer.valueOf(c.get(2) + 1);
        Integer day = Integer.valueOf(c.get(5));
        FSchedue query = new FSchedue();
        query.setTenantId(tenantId);
        query.setScheduleYear(year);
        query.setScheduleMonth(month);
        query.setScheduleDay(day);
        List<FSchedue> list = this.fSchedueService.findList(query);
        if (list.size() > 1 || list.size() == 0)
            throw new Exception("数据异常");
        query = list.get(0);
        Integer count = Integer.valueOf(0);
        if (index.intValue() == 1) {
            count = query.getCountA();
            query.setCountA(Integer.valueOf(query.getCountA().intValue() - 1));
        } else if (index.intValue() == 2) {
            count = query.getCountB();
            query.setCountB(Integer.valueOf(query.getCountB().intValue() - 1));
        } else if (index.intValue() == 3) {
            count = query.getCountC();
            query.setCountC(Integer.valueOf(query.getCountC().intValue() - 1));
        } else if (index.intValue() == 4) {
            count = query.getCountD();
            query.setCountD(Integer.valueOf(query.getCountD().intValue() - 1));
        } else if (index.intValue() == 5) {
            count = query.getCountE();
            query.setCountE(Integer.valueOf(query.getCountE().intValue() - 1));
        }
        if (count.intValue() <= 0)
            throw new Exception("该时间段已约满，请更换时间段");
        this.fSchedueService.save(query);
        TTenant tenant = this.tTenantService.get(tenantId.toString());
        TOrder tOrder = new TOrder();
        tOrder.setDelFlag("0");
        tOrder.setOpenId(openId);
        tOrder.setPatientId(patientId);
        tOrder.setTenantId(tenantId);
        tOrder.setBookDateType(index);
        tOrder.setBookDateDetail(title);
        tOrder.setBookDate(bookDate);
        tOrder.setTenantName(tenant.getTenantName());
        tOrder.setTenantAddress(tenant.getAddress());
        tOrder.setPatientName(tPatient.getPatientName());
        tOrder.setPatientAddress(tPatient.getGender().toString());
        tOrder.setPatientMobile(tPatient.getMobile());
        tOrder.setPatientCard(tPatient.getCard());
        tOrder.setOrderNo(IdGen.getOrderNo());
        tOrder.setStatus(Integer.valueOf(1));
        tOrder.setBookNo(Integer.valueOf(oldOrders.size() + 1));
        tOrder.setOfficeName(beginDate + "-" + endDate);
        save(tOrder);
    }

    @Transactional(readOnly = false, rollbackFor = {Exception.class})
    public void createOrder(Integer actionId, Integer bookId, Integer patientId, String openId, Integer nowTenantId) throws Exception {
        if (bookId == null || patientId == null || StringUtils.isBlank(openId))
            throw new Exception("参数错误");
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
        TOrder tOrder = new TOrder();
        tOrder.setDelFlag("0");
        TBookNo tBookNo = this.tBookNoService.get(bookId.toString());
        TDoctor tDoctor = this.tDoctorService.get(tBookNo.getDoctorId().toString());
        TPatient tPatient = this.tPatientService.get(patientId.toString());
        TTenant tTenant = this.tTenantService.get(tBookNo.getTenantId().toString());
        TOrder queryOrder = new TOrder();
        queryOrder.setTenantId(tBookNo.getTenantId());
        queryOrder.setDoctorId(tBookNo.getDoctorId());
        queryOrder.setActionId(actionId);
        queryOrder.setPatientId(patientId);
        queryOrder.setOpenId(openId);
        queryOrder.setBookDate(sdf.parse(tBookNo.getBookYear() + "-" + tBookNo.getBookMonth() + "-" + tBookNo.getBookDay()));
        queryOrder.setBookDateType(tBookNo.getType());
        queryOrder.setWithOutCancel(Integer.valueOf(1));
        List<TOrder> queryList = findList(queryOrder);
        if (!queryList.isEmpty())
            throw new Exception("就诊人：" + tPatient.getPatientName() + "，在" + tBookNo
                    .getBookYear() + "-" + tBookNo.getBookMonth() + "-" + tBookNo.getBookDay() + (
                    (tBookNo.getType().intValue() == 1) ? " 上午" : " 下午") + " 时间段已有预约号，请取消后方可再约");
        tOrder.setBookId(bookId);
        tOrder.setOpenId(openId);
        tOrder.setActionId(actionId);
        tOrder.setTenantId(tBookNo.getTenantId());
        tOrder.setPatientId(patientId);
        tOrder.setOfficeId(tBookNo.getOfficeId());
        tOrder.setDoctorId(tBookNo.getDoctorId());
        tOrder.setRankId(tDoctor.getRankId());
        tOrder.setProRankId(tDoctor.getProStatus());
        tOrder.setTenantName(tTenant.getTenantName());
        tOrder.setTenantAddress(tTenant.getAddress());
        tOrder.setPatientName(tPatient.getPatientName());
        tOrder.setPatientAddress(tPatient.getAddress());
        tOrder.setPatientMobile(tPatient.getMobile());
        tOrder.setPatientCard(tPatient.getCard());
        tOrder.setOfficeName(tDoctor.getOffice().getOfficeName());
        tOrder.setDoctorName(tDoctor.getDoctorName());
        tOrder.setDoctorPicUrl(tDoctor.getPic());
        tOrder.setRankName(tDoctor.gettRank().getRankName());
        tOrder.setType(Integer.valueOf((actionId == null) ? TOrder.type_normal : TOrder.type_phy));
        tOrder.setOrderNo(IdGen.getOrderNo());
        tOrder.setStatus(Integer.valueOf((actionId == null) ? 1 : 8));
        tOrder.setBookDate(sdf.parse(tBookNo.getBookYear() + "-" + tBookNo.getBookMonth() + "-" + tBookNo.getBookDay()));
        tOrder.setBookDateType(tBookNo.getType());
        tOrder.setBookDateDetail(tBookNo.getBookTime());
        tOrder.setBookNo(tBookNo.getBookNo());
        tOrder.setPayAmount(BigDecimal.ZERO);
        tOrder.setPayDate(new Date());
        tOrder.setProRankName(nowTenantId.toString());
        tDoctor.setUseNum(Integer.valueOf(tDoctor.getUseNum().intValue() + 1));
        this.tDoctorService.save(tDoctor);
        synchronized (tBookNo.getId()) {
            tBookNo = this.tBookNoService.get(tBookNo.getId());
            if (tBookNo.getStatus().intValue() == 1)
                throw new Exception("来晚了，该号已被预约，请刷新页面");
            tBookNo.setStatus(Integer.valueOf(1));
            this.tBookNoService.save(tBookNo);
        }
        if (actionId != null) {
            synchronized (actionId) {
                TStock stock = this.tStockService.getByParam(tBookNo.getTenantId(), actionId, tBookNo.getDoctorId(), tBookNo.getBookYear(), tBookNo
                        .getBookMonth(), tBookNo.getBookDay(), tBookNo.getType());
                if (stock != null) {
                    if (stock.getStock().intValue() <= 0)
                        throw new Exception("库存不足，请刷新页面！");
                    stock.setStock(Integer.valueOf(stock.getStock().intValue() - 1));
                } else {
                    stock = new TStock();
                    stock.setTenantId(tBookNo.getTenantId());
                    TAction tAction = this.tActionService.get(actionId.toString());
                    stock.setActionId(actionId);
                    stock.setDoctorId(tBookNo.getDoctorId());
                    stock.setStockYear(tBookNo.getBookYear());
                    stock.setStockMonth(tBookNo.getBookMonth());
                    stock.setStockDay(tBookNo.getBookDay());
                    stock.setStock(Integer.valueOf((tBookNo.getType().intValue() == 1) ? (tAction.getAmStock().intValue() - 1) : (tAction.getPmStock().intValue() - 1)));
                    stock.setType(tBookNo.getType());
                }
                this.tStockService.save(stock);
                tOrder.setStockId(Integer.valueOf(Integer.parseInt(stock.getId())));
                save(tOrder);
                tOrder = getByOrderNo(tOrder.getOrderNo());
                TTempNotice tTempNotice = this.tTempNoticeService.getByParam(tOrder.getTenantId(), Integer.valueOf(TTempNotice.retailSuccess));
                if (tTempNotice != null && tTempNotice.getStatus().intValue() == 1) {
                    tOrder.setTenantId(nowTenantId);
                    String data = TempNoticeUtil.getRetailSuccess(tTempNotice.getTempId(), tOrder);
                    TWeixinConfig wc = this.tWeixinConfigService.findByTenantId(tOrder.getTenantId());
                    PlatformAccount account = new PlatformAccount(wc);
                    String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + account.getAccessToken();
                    JSONObject jsonObject = WxOpenUtil.httpPost(url, data);
                    this.logger.info("jo:" + jsonObject.toString());
                }
            }
            return;
        }
        synchronized (tDoctor.getId()) {
            TStock stock = this.tStockService.getByParam(tBookNo.getTenantId(), null, tBookNo.getDoctorId(), tBookNo.getBookYear(), tBookNo
                    .getBookMonth(), tBookNo.getBookDay(), tBookNo.getType());
            if (stock != null) {
                if (stock.getStock().intValue() <= 0)
                    throw new Exception("库存不足，请刷新页面！");
                stock.setStock(Integer.valueOf(stock.getStock().intValue() - 1));
            } else {
                stock = new TStock();
                stock.setTenantId(tBookNo.getTenantId());
                TSchedue schedue = this.tSchedueService.findByDoctorId(tBookNo.getTenantId(), tBookNo.getDoctorId(), tBookNo.getBookYear(), tBookNo.getBookMonth());
                StockDto DataStock = TSchedueTemplateService.getStock(schedue, tBookNo.getBookDay());
                stock.setDoctorId(tBookNo.getDoctorId());
                stock.setStockYear(tBookNo.getBookYear());
                stock.setStockMonth(tBookNo.getBookMonth());
                stock.setStockDay(tBookNo.getBookDay());
                stock.setStock(Integer.valueOf((tBookNo.getType().intValue() == 1) ? (DataStock.getAmStock().intValue() - 1) : (DataStock.getPmStock().intValue() - 1)));
                stock.setType(tBookNo.getType());
            }
            this.tStockService.save(stock);
            tOrder.setStockId(Integer.valueOf(Integer.parseInt(stock.getId())));
            save(tOrder);
            tOrder = getByOrderNo(tOrder.getOrderNo());
        }
        TTempNotice tempNotice = this.tTempNoticeService.getByParam(tOrder.getTenantId(), Integer.valueOf(TTempNotice.appointSuccess));
        if (tempNotice != null && tempNotice.getStatus().intValue() == 1) {
            String data = TempNoticeUtil.getAppointSuccess(tempNotice.getTempId(), tOrder);
            TWeixinConfig wc = this.tWeixinConfigService.findByTenantId(tOrder.getTenantId());
            PlatformAccount account = new PlatformAccount(wc);
            String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + account.getAccessToken();
            JSONObject jSONObject = WxOpenUtil.httpPost(url, data);
        }
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, readOnly = false, rollbackFor = {Exception.class})
    public void cancelAppoint(Integer tenantId, Integer orderId, String openId) throws Exception {
        if (StringUtils.isBlank(openId) || tenantId == null)
            throw new Exception("参数错误");
        TOrder tOrder = get(orderId.toString());
        Integer status = tOrder.getStatus();
        if (!tOrder.getOpenId().equals(openId))
            throw new Exception("传递信息有误");
        if (tOrder.getBookDate().getTime() <= (new Date()).getTime()) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            throw new Exception("仅在" + sdf.format(tOrder.getBookDate()) + "前，允许取消");
        }
        if (status.intValue() == 1) {
            tOrder.getTenantId();
            Calendar c = Calendar.getInstance();
            c.setTime(tOrder.getBookDate());
            Integer year = Integer.valueOf(c.get(1));
            Integer month = Integer.valueOf(c.get(2) + 1);
            Integer day = Integer.valueOf(c.get(5));
            FSchedue query = new FSchedue();
            query.setScheduleYear(year);
            query.setTenantId(tenantId);
            query.setScheduleMonth(month);
            query.setScheduleDay(day);
            List<FSchedue> list = this.fSchedueService.findList(query);
            if (list.size() > 1 || list.size() == 0)
                throw new Exception("数据异常");
            query = list.get(0);
            query = this.fSchedueDao.getForLock(query.getId());
            Integer index = tOrder.getBookDateType();
            if (index.intValue() == 1) {
                query.setCountA(Integer.valueOf(query.getCountA().intValue() + 1));
            } else if (index.intValue() == 2) {
                query.setCountB(Integer.valueOf(query.getCountB().intValue() + 1));
            } else if (index.intValue() == 3) {
                query.setCountC(Integer.valueOf(query.getCountC().intValue() + 1));
            } else if (index.intValue() == 4) {
                query.setCountD(Integer.valueOf(query.getCountD().intValue() + 1));
            } else if (index.intValue() == 5) {
                query.setCountE(Integer.valueOf(query.getCountE().intValue() + 1));
            }
            this.fSchedueDao.update(query);
            tOrder.setStatus(Integer.valueOf(11));
            save(tOrder);
            TOrder orderQuery = new TOrder();
            orderQuery.setTenantId(tenantId);
            orderQuery.setStatus(Integer.valueOf(11));
            orderQuery.setPatientCard(tOrder.getPatientCard());
            orderQuery.setQueryOrderNo(String.valueOf(year).substring(2) + month);
            List<TOrder> oldOrders = findList(orderQuery);
            if (oldOrders.size() >= 2) {
                List<String> cancelThreeList = AppointSchedule.getCancelThreeList();
                cancelThreeList.add(tenantId + tOrder.getPatientCard());
            }
        } else {
            throw new Exception("订单状态异常，请刷新页面");
        }
    }

    @Transactional(readOnly = false)
    public void updateStatusByOrderList(List<TOrder> orderList, int status, String reason) {
        ((TOrderDao) this.dao).updateStatusByOrderList(orderList, status, reason);
    }

    public void chechBook(Integer bookId, String openId, Integer actionId) throws Exception {
    }

    @Transactional(readOnly = false)
    public void onlineSave(Integer tPatienttId, String bookDate, Integer type) throws Exception {
        FSchedue fSchedue = new FSchedue();
        Date BookDate = (new SimpleDateFormat("yyyy-MM-dd")).parse(bookDate);
        if (DateUtils.getDistanceOfTwoDate(new Date(), BookDate) < 0.0D)
            throw new Exception("预约日期不小于当日");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(BookDate);
        fSchedue.setScheduleYear(Integer.valueOf(calendar.get(1)));
        fSchedue.setScheduleMonth(Integer.valueOf(calendar.get(2) + 1));
        fSchedue.setScheduleDay(Integer.valueOf(calendar.get(5)));
        fSchedue.setDelFlag("0");
        fSchedue.setTenantId(Integer.valueOf(5));
        List<FSchedue> list = this.fSchedueService.findList(fSchedue);
        if (list.size() == 0 || list.size() > 1)
            throw new Exception("数据异常");
        FSchedue schedue = list.get(0);
        Integer total = null;
        String bookDateDetail = null;
        String beginDate = null;
        String endDate = null;
        if (type.intValue() == 1) {
            total = schedue.getTotalA();
            bookDateDetail = schedue.getTitleA();
            beginDate = schedue.getBeginDateA();
            endDate = schedue.getEndDateA();
        } else if (type.intValue() == 2) {
            total = schedue.getTotalB();
            bookDateDetail = schedue.getTitleB();
            beginDate = schedue.getBeginDateB();
            endDate = schedue.getEndDateB();
        } else if (type.intValue() == 3) {
            total = schedue.getTotalC();
            bookDateDetail = schedue.getTitleC();
            beginDate = schedue.getBeginDateC();
            endDate = schedue.getEndDateC();
        } else if (type.intValue() == 4) {
            total = schedue.getTotalD();
            bookDateDetail = schedue.getTitleD();
            beginDate = schedue.getBeginDateD();
            endDate = schedue.getEndDateD();
        } else if (type.intValue() == 5) {
            total = schedue.getTotalE();
            bookDateDetail = schedue.getTitleE();
            beginDate = schedue.getBeginDateE();
            endDate = schedue.getEndDateE();
        }
        if (total.intValue() == 0)
            throw new Exception("所选日期或时间段没有号源");
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        TOrder tOrder = new TOrder();
        tOrder.setOnlineType(Integer.valueOf(1));
        tOrder.setQueryBookDateUp(calendar.getTime());
        calendar.add(6, 1);
        tOrder.setQueryBookDateDown(calendar.getTime());
        tOrder.setBookDateType(type);
        List<TOrder> orders = findList(tOrder);
        int no = total.intValue() + orders.size() + 1;
        TPatient tPatient = this.tPatientService.get(tPatienttId.toString());
        TTenant tenant = this.tTenantService.get("5");
        tOrder = new TOrder();
        tOrder.setDelFlag("0");
        tOrder.setOpenId(tPatient.getOpenId());
        tOrder.setPatientId(tPatienttId);
        tOrder.setTenantId(Integer.valueOf(5));
        tOrder.setBookDateType(type);
        tOrder.setBookDateDetail(bookDateDetail);
        tOrder.setBookDate(BookDate);
        tOrder.setTenantName(tenant.getTenantName());
        tOrder.setTenantAddress(tenant.getAddress());
        tOrder.setPatientName(tPatient.getPatientName());
        tOrder.setPatientAddress(tPatient.getGender().toString());
        tOrder.setPatientMobile(tPatient.getMobile());
        tOrder.setPatientCard(tPatient.getCard());
        tOrder.setOrderNo(IdGen.getOrderNo());
        tOrder.setStatus(Integer.valueOf(1));
        tOrder.setOnlineType(Integer.valueOf(1));
        tOrder.setBookNo(Integer.valueOf(no));
        tOrder.setOfficeName(beginDate + "-" + endDate);
        tOrder.preInsert();
        ((TOrderDao) this.dao).insert(tOrder);
    }
}
